package com.alibaba.csp.sentinel.dashboard.rule.nacos;

/**
 * packageName com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosDynamicRuleProvider
 *
 * @author liudonghai
 * @version JDK 11
 * @date 2025/8/3
 * @description provide抽象类
 */
import com.alibaba.csp.sentinel.dashboard.config.NacosRuleConstants;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

public abstract class NacosDynamicRuleProvider<T extends RuleEntity> implements com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider<List<T>> {

    private static final Logger logger = LoggerFactory.getLogger(NacosDynamicRuleProvider.class);

    private ConfigService configService;

    public NacosDynamicRuleProvider(ConfigService configService) {
        this.configService = configService;
    }

    /**
     * 获取数据ID后缀
     * @return 数据ID后缀
     */
    protected abstract String getDataIdPostfix();

    /**
     * 获取规则类型
     * @return 规则类型Class
     */
    protected abstract Class<T> getRuleClass();

    /**
     * 生成数据ID
     * @param appName 应用名称
     * @return 完整数据ID
     */
    private String genDataId(String appName) {
        return appName + getDataIdPostfix();
    }

    @Override
    public List<T> getRules(String app) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        String dataId = genDataId(app);
        String rules = configService.getConfig(dataId, NacosRuleConstants.GROUP_ID, 3000);
        logger.info("Get rules from Nacos, dataId: {}, rules: {}", dataId, rules);
        if (StringUtil.isEmpty(rules)) {
            return new ArrayList<>();
        }
        return JSON.parseArray(rules, getRuleClass());
    }
}

